﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Db4objects.Db4o;
using StockFinder.Model;
using StockFinder.Model.Constants;
using Db4objects.Db4o.Config;
using log4net;

namespace StockFinder.Services.Engines
{
    public class MarketObserverUpdater
    {
        private static readonly ILog _Log = LogManager.GetLogger(typeof(MarketObserverUpdater)); 

        public void Run()
        {
            using (IObjectContainer marketObserverDatabase = Db4oEmbedded.OpenFile(GeCreateIEmbeddedConfiguration(),
                ApplicationConfiguation.ObjectDatabaseSRootDirectory + ObjectDatabaseFilenames.MARKET_OBSERVER))            
            using (IObjectContainer priceHistoryDatabase = Db4oEmbedded.OpenFile(GeCreateIEmbeddedConfiguration(),
                ApplicationConfiguation.ObjectDatabaseSRootDirectory + ObjectDatabaseFilenames.PRICE_HISTORY))
            {
                #region Get Price History Container
                PriceHistoryContainer priceHistoryContainer = null;

                //get or create PriceHistoryContainer
                List<PriceHistoryContainer> priceHistoryContainers = priceHistoryDatabase.Query<PriceHistoryContainer>().ToList();

                //PriceHistoryContainer doesnt exist so create it
                if (priceHistoryContainers == null || priceHistoryContainers.Count() == 0)
                {
                    throw new Exception("Couldnt find any PriceHistoryContainers");
                }
                else
                {
                    //should only be 1 price history container
                    priceHistoryContainer = priceHistoryContainers[0];
                }
                
                #endregion

                #region Get Market Observer Container
                MarketObserverContainer marketObserverContainer = null;

                List<MarketObserverContainer> marketObserverContainers = marketObserverDatabase.Query<MarketObserverContainer>().ToList();

                if (marketObserverContainers == null || marketObserverContainers.Count == 0)
                {
                    throw new Exception("Couldnt find any MarketObserverContainers");
                }
                else
                {
                    marketObserverContainer = marketObserverContainers[0];
                }                

                #endregion

                //get symbol list into memory
                priceHistoryDatabase.Activate(priceHistoryContainer.Symbols, 2);

                //get the history into memory
                marketObserverDatabase.Activate(marketObserverContainer.MarketObservationItems, 3);

                Symbol symbol = null;

                for (int i = 0; i < priceHistoryContainer.Symbols.Count; i++)
                {
                    symbol = priceHistoryContainer.Symbols[i];

                    _Log.InfoFormat("Updating {0} price history", symbol.Name);

                    //now activate symbols prices list
                    priceHistoryDatabase.Activate(symbol.Prices, 2);

                    if (symbol.Prices.Count == 0)
                    {                       
                        _Log.Warn("Has no prices");                        
                    }
                        //make sure this stock prices is current
                    else if (symbol.Prices.Last().PriceDate != priceHistoryContainer.LastPriceDate)
                    {
                        _Log.WarnFormat("Different last price dates. Container: {0}. Symbol: {1}",
                            priceHistoryContainer.LastPriceDate, symbol.Prices.Last().PriceDate); 
                    }
                    else
                    {
                        //run market observer calculations

                    }
                }
            }
        }

        private IEmbeddedConfiguration GeCreateIEmbeddedConfiguration()
        {
            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            config.Common.ActivationDepth = 1;
            config.File.BlockSize = 8;
            //config.Common.ObjectClass(typeof(PriceHistoryContainer)).CascadeOnUpdate(true);
            //config.Common.ObjectClass(typeof(DailyPrice)).CascadeOnUpdate(true);
            //config.Common.ObjectClass(typeof(Symbol)).CascadeOnUpdate(true);

            return config;
        }
    }
}
